<!DOCTYPE html>
<html>

<head>
    <title>groupgl bloom test</title>
    <script type="text/javascript" src="https://unpkg.com/lz-string@1.4.4/libs/lz-string.min.js"></script>
    <script type="text/javascript" src="https://unpkg.com/dat.gui@0.7.6/build/dat.gui.min.js"></script>
    <link type="text/css" rel="stylesheet" href="https://unpkg.com/maptalks/dist/maptalks.css">
    <script type="text/javascript" src="https://unpkg.com/maptalks/dist/maptalks.js"></script>
    <script type="text/javascript" src="https://unpkg.com/@maptalks/gl/dist/maptalksgl.js"></script>
    <script type="text/javascript" src="https://unpkg.com/three@0.138.0/build/three.min.js"></script>
    <script type="text/javascript" src="https://unpkg.com/maptalks.three@latest/dist/maptalks.three.js"></script>
    <script type="text/javascript" src="buildings.js"></script>
    <style>
        html,
        body {
            margin: 0px;
            height: 100%;
            width: 100%;
        }

        #map {
            width: 100%;
            height: 100%;
            background-color: #000;
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <script>

        var map = new maptalks.Map("map", {
            "center": [13.410135891859682, 52.52930791588827], "zoom": 16, "pitch": 72.80000000000005, "bearing": 168.6359466350949,

            centerCross: true,
            doubleClickZoom: false,
            // baseLayer: new maptalks.TileLayer('tile', {
            //     urlTemplate: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
            //     subdomains: ['a', 'b', 'c', 'd'],
            //     attribution: '&copy; <a href="http://osm.org">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/">CARTO</a>'
            // })
        });

        // features to draw
        var features = [];

        buildings.forEach(function (b) {
            features = features.concat(b.features);
        });

        // the ThreeLayer to draw buildings
        var threeLayer = new maptalks.ThreeLayer('t', {
            forceRenderOnMoving: true,
            forceRenderOnRotating: true
            // animation: true
        });

        var meshs = [];
        var material = new THREE.MeshPhongMaterial({ color: 'rgb(255,255,255)', transparent: true });
        var highlightmaterial = new THREE.MeshBasicMaterial({ color: 'red', transparent: true });
        threeLayer.prepareToDraw = function (gl, scene, camera) {
            var light = new THREE.DirectionalLight(0xffffff);
            light.position.set(0, -10, 10).normalize();
            scene.add(light);
            scene.add(new THREE.AmbientLight('#fff', 0.2));

            threeLayer.config('animation', true);
            addBuildings();
            addLines();
        };


        function addBuildings() {
            features.slice(0, 10000).forEach(function (g, index) {
                var heightPerLevel = 10;
                var levels = g.properties.levels || 1;
                const height = levels * heightPerLevel;
                var mesh = threeLayer.toExtrudePolygon(maptalks.GeoJSON.toGeometry(g), {
                    height: height,
                    topColor: '#fff',
                    asynchronous: true,
                    bloom: height > 100
                }, material);

                //event test
                ['click', 'mousemove', 'mouseout', 'mouseover', 'mousedown', 'mouseup', 'dblclick', 'contextmenu'].forEach(function (eventType) {
                    mesh.on(eventType, function (e) {
                        // console.log(e.type, e);
                        // console.log(this);
                        if (e.type === 'mouseout') {
                            this.setSymbol(material);
                        }
                        if (e.type === 'mouseover') {
                            this.setSymbol(highlightmaterial);
                        }
                    });
                });
                meshs.push(mesh);
            });
            threeLayer.addMesh(meshs);
        }

        var lineMaterial = new THREE.LineBasicMaterial({
            linewidth: 1,
            color: 'rgb(255,90,0)',
            opacity: 1,
            transparent: true,
            blending: THREE.AdditiveBlending,
        });
        var lines;

        function addLines() {
            fetch('./data/berlin-roads.txt').then(function (res) {
                return res.text();
            }).then(function (geojson) {
                geojson = LZString.decompressFromBase64(geojson);
                geojson = JSON.parse(geojson);
                lines = threeLayer.toLines(geojson.features, { altitude: 0, bloom: true }, lineMaterial);
                threeLayer.addMesh(lines);
                initGui();
            })
        }

        const sceneConfig = {
            postProcess: {
                enable: true,
                antialias: { enable: true },
                bloom: {
                    enable: true,
                    threshold: 0,
                    factor: 1,
                    radius: 0.02,
                },
            }
        };
        const groupLayer = new maptalks.GroupGLLayer('group', [threeLayer], { sceneConfig });
        groupLayer.addTo(map);


        function initGui() {
            var params = {
                bloom: sceneConfig.postProcess.bloom.enable,
                add: true,
                color: material.color.getStyle(),
                show: true,
                opacity: 1,
                altitude: 0,
                lineColor: lineMaterial.color.getStyle(),
                lineOpacity: lineMaterial.opacity,
                lineBloom: lines.options.bloom
            };
            var gui = new dat.GUI({ width: 350 });
            gui.add(params, 'bloom').name('global bloom').onChange(function () {
                sceneConfig.postProcess.bloom.enable = params.bloom;
            });
            gui.add(params, 'add').onChange(function () {
                if (params.add) {
                    threeLayer.addMesh(meshs).addMesh(lines);
                } else {
                    threeLayer.removeMesh(meshs).removeMesh(lines);
                }
            });
            gui.add(params, 'show').onChange(function () {
                meshs.concat([lines]).forEach(function (mesh) {
                    if (params.show) {
                        mesh.show();
                    } else {
                        mesh.hide();
                    }
                });
            });
            gui.add(params, 'altitude', 0, 300).onChange(function () {
                meshs.concat([lines]).forEach(function (mesh) {
                    mesh.setAltitude(params.altitude);
                });
            });
            gui.addColor(params, 'color').name('building color').onChange(function () {
                material.color.set(params.color);
                meshs.forEach(function (mesh) {
                    mesh.setSymbol(material);
                });
            });
            gui.add(params, 'opacity', 0, 1).name('building opacity').onChange(function () {
                material.opacity = params.opacity;
                meshs.forEach(function (mesh) {
                    mesh.setSymbol(material);
                });
            });
            gui.addColor(params, 'lineColor').name('line color').onChange(function () {
                lineMaterial.color.set(params.lineColor);
            });
            gui.add(params, 'lineOpacity', 0, 1).name('line opacity').onChange(function () {
                lineMaterial.opacity = params.lineOpacity;

            });
            gui.add(params, 'lineBloom').name('line bloom').onChange(function () {
                lines.options.bloom = params.lineBloom;
            });
        }






    </script>
</body>

</html>